Release 10.1A: OpenEdge Development:
ProDataSets
Setting up an event handler for the FIND-FAILED buffer event
We can extend the example even further to show how to use the
FIND-FAILEDevent. This ProDataSet buffer event is similar to theOFF-ENDevent on a query in that it gives your application the opportunity to retrieve missing data without the rest of the application even being aware that it wasn’t in the ProDataSet in the first place. You can use the event to retrieve needed rows one at a time, or in batches, depending on the situation.
![]()
To show how the event works:
- Add a callback for a
FIND-FAILEDevent handler to theLEAVEtrigger forSalesRepinPickOrderBatch.w, right after the callback for theOFF-ENDevent. For example:
Note that the
OFF-ENDevent must be attached to a query, and theFIND-FAILEDevent to a ProDataSet buffer, in this case thettItembuffer, which will allow the procedure to retrieveItemsto add to the browse the first time they are referenced.- Change the call to
fetchOrderDetailin theMOUSE-SELECT-DBLCLICKtrigger for theOrderbrowse as you have done in another variation of this procedure, to remove the second parameter that tellsfetchOrderDetailwhether items have been retrieved or not, as shown:
In this case,
fetchOrderDetailwill never return anyItems. They will be retrieved one at a time as they’re needed.- Edit the
fetchOrderDetailinternal procedure inOrderSupportBatch.pto remove the second parameter. In addition, set theFILL-MODEforttItemto beNO-FILL, unconditionally. This means thatfetchOrderDetailwill return onlyOrderLinesfor the currentOrder, and noItems. For example:
- Now code the
FindFailedIteminternal procedure inPickOrderBatch.w, as shown:
As with all callbacks, this one gets the ProDataSet as
INPUT. It runs a new procedure called fetchItem, which you’ll write in a moment, which accepts the neededItemnumber and returns itsItemName. As always with callbacks, the buffer in the appropriate temp-table in the ProDataSet parameter holds the row that was current when the event occurred. In this case Progress is attempting to reposition thettItembrowse each time you select attOlinerow in its browse. To do this, Progress is doing the equivalent of aFINDstatement internally. When theItemis not already there, theFIND-FAILEDevent occurs, giving your event handler the opportunity to add the neededItemto the client. Since the browse shows only theItemNumandItemNamefields,fetchItemonly needs to return the name. You then create a newttItemtemp-table row for that item, andRETURN NO-APPLY. This tells Progress to ignore the failure and try to locate the row again, transparent to wherever the find failed. This now succeeds, and the newItemappears in its browse and becomes the currently selected row.- Finally, write the new
fetchItemprocedure inOrderSupportBatch.p, as shown:
This accepts the current
ItemNum, which the window procedure discovered that it didn’t have when it tried to reposition theItembrowse when you select anOrderLine. It finds the database record for thatItemand returns itsItemName. Since you’re just returning a single field, there’s no need to do aFILL. That would be overkill in this case.- Save all of this and rerun
PickOrderBatch.w. Enter some selection criteria forOrders, such asCustomer 1, tab through the fill-ins, and then double-click on anOrderto retrieve itsOrderLines.When you do this, your modified version of
fetchOrderDetailis not returning anyItems. Only when you select anOrderLinedoes Progress detect that itsItemis missing, because there’s no row for it to reposition theItembrowse to. This fires yourFIND-FAILEDevent handler, which retrieves that oneItem, and adds it to the temp-table. By executing aRETURN NO-APPLY, the handler tells Progress to ignore the failure and retry the reposition. Now it succeeds, as shown:
![]()
As you continue to select
OrderLines, Progress continues to retrieve eachItemthe first time it’s needed, adding it to thettItemtemp-table and to the browse, as shown:
![]()
Note that because you’ve created a general-purpose event handler for any
FINDon thettItemtable that fails, any other action your client might take that tries to find attItemrow unsuccessfully will automatically trigger the same handler, and will transparently add the row to the temp-table and make the row available to the statement that needed it, without that statement or its surrounding code needing to do anything special to allow for the possibility that the row is not yet there when it is first referenced. This is the value of the event handlers, that they execute whenever they are needed within the session.Retrieving rows to cache on the client one at a time may not be a good strategy in many cases. Your
FIND-FAILEDhandler could also retrieve batches of rows up to the one that is needed, or batches of related rows that are likely to be needed by the client. In any case, theFIND-FAILEDevent is just one more tool you can use to make batching and caching data in your ProDataSets as transparent as possible.
|
Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |